package io.lckgroup.modules.lck.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.lckgroup.common.exception.BackException;
import io.lckgroup.common.utils.R;
import io.lckgroup.common.utils.RedisUtils;
import io.lckgroup.modules.lck.utils.order.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName: OrderController
 * @Author: zhao_ag
 * @Date: 2020-03-23 14:01
 * @Version: 1.0
 * 订单控制类
 */
@RestController
@RequestMapping("app/order")
public class OrderController {

    @Autowired
    RedisUtils redisUtils;

    static String LC_Url = "https://lzwxsd.lzccb.cn/payGateway/";

    /**
     * sm2私钥。非公钥
     */
    static String sm2PriKey = "00985451BB1B015AF1AC5C14614A2DEB9CB39B6B392070E3DAFEADA417CC481FA9";

    /**
     * 签名秘钥
     */
    static String signKey = "k9PbGc+a+pv+egpATAKG4HDetOlmG0Hkc9KFlFYoDSg=";

    private SMSaltSigner signer = new SMSaltSigner();

    private static Map<String, String> headerMap;

    static {
        headerMap = new HashMap<>();
        headerMap.put("Key-Sn", "1");
        headerMap.put("Alg-Sn", "1");
    }

    /**
     * 查询泸州银行订单状态信息
     *
     * @param merchantNo 商户号
     * @param outTradeNo 订单号
     * @param storeId    门店号
     * @param terminalId 机具号
     * @return
     * @throws Exception
     */
    @RequestMapping("query")
    public R query(String merchantNo, String outTradeNo, String storeId, String terminalId) throws Exception {
        headerMap.put("Time-Stamp", DateUtils.format(new Date(), "yyyyMMddHHmmss"));
        headerMap.put("Mer-Id", merchantNo);
        // sm2秘钥。其对应公钥，需要发送给支付通道
        // 获得sm4加密秘钥，获得后可存到redis中，下一次使用就不用再次获取
        String sm4Key = getSm4Key(sm2PriKey, 0, merchantNo);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("outTradeNo", outTradeNo);
        jsonObject.put("merchantNo", merchantNo);
        jsonObject.put("storeId", storeId);
        jsonObject.put("terminalId", terminalId);
        System.out.println("请求参数 = " + jsonObject.toJSONString());
        String reqStr = jsonObject.toJSONString();
        reqStr = signer.encryptData(sm4Key, reqStr);
        ISignBlock signBlock = new BodySignBlock("/payGateway/zlxt/trade/query", merchantNo, headerMap.get("Time-Stamp"), reqStr);
        String sign = signer.sign(signBlock, signKey);
        headerMap.put("Sign", sign);
        ZLResponse zlResponse = HttpUtil.doPost(LC_Url + "zlxt/trade/query", reqStr, headerMap);
        String retStr = zlResponse.getRetStr();
        String retSign = zlResponse.getSign();
        // 当通道对数据进行解密和签名校验失败时，返回的是明文。
        signBlock = new BodySignBlock("/payGateway/" + "zlxt/trade/query", merchantNo, headerMap.get("Time-Stamp"), retStr);
        if (!signer.sign(signBlock, signKey).equals(retSign)) {
            throw new BackException("返回签名验证失败");
        }

        retStr = signer.decryptData(sm4Key, retStr);
        Map map = JSONObject.parseObject(retStr);
        return R.ok(map);
    }

    /**
     * 获得sm4秘钥。获得后可存到redis中，下一次使用就不用再次获取
     *
     * @throws Exception
     */
    private String getSm4Key(String sm2PriKey, int isRefresh, String merchantNo) {
        Object o = redisUtils.get(merchantNo);
        if (o != null) {
            String sm4Key = String.valueOf(o);
            return sm4Key;
        }
        JSONObject reqJson = new JSONObject();
        reqJson.put("isRefresh", isRefresh);
        String reqStr = reqJson.toJSONString();
        ISignBlock signBlock = new BodySignBlock("/payGateway/payApi/merchant/getSm4Key", merchantNo, headerMap.get("Time-Stamp"), reqJson.toString());
        String sign = signer.sign(signBlock, signKey);
        headerMap.put("Sign", sign);
        ZLResponse zlResponse = null;
        try {
            zlResponse = HttpUtil.doPost(LC_Url + "payApi/merchant/getSm4Key", reqStr, headerMap);
        } catch (Exception e) {
            new BackException("获取SM4秘钥失败，请重试");
        }
        String retStr = zlResponse.getRetStr();
        if (retStr == null) {
            throw new BackException("获取SM4异常");
        }
        Rsp rsp = JSON.parseObject(retStr, Rsp.class);
        if (rsp.successed()) {
            JSONObject data = (JSONObject) rsp.getData();
            String sm4Key = data.getString("sm4Key");
            sm4Key = signer.decryptSm2(sm2PriKey, sm4Key);
            redisUtils.set(merchantNo, sm4Key);
            return sm4Key;
        }
        throw new BackException(rsp.getMsg());
    }
}
